package services

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/internal/pkg/modelbase"
	"TaskAssignmentSystem/pkg/db/mysql"
	"errors"
	"fmt"
	"github.com/wxnacy/wgo/arrays"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"math"
	"time"
)

type UserService struct {
}

const (
	UserIsAuthenticationTrue  = 1
	UserIsAuthenticationFalse = 0
)

func (u *UserService) ExcelBatchUpdate(query map[string]interface{}, userObj dao.SystemUser, mouthed int) (err error) {
	//1：新增权限；2：删除权限；3：覆盖权限）
	var _db = mysql.GetDB()
	err = _db.Transaction(func(tx *gorm.DB) error {
		var user dao.SystemUser
		//if mouthed == 2 || mouthed == 3 {
		if err := tx.Model(&dao.SystemUser{}).Preload(clause.Associations).Where(query).First(&user).Error; err != nil {
			return err
		}
		//}
		if mouthed != 1 {
			//删除用户关联的 restriction中的数据
			if err := tx.Model(&dao.SystemUserRestriction{}).Where(map[string]interface{}{"system_user_id": user.Id}).Unscoped().Delete(&dao.SystemUserRestriction{}).Error; err != nil {
				return err
			}
		}
		//保存新的数据
		user.TeamNumber = userObj.TeamNumber
		user.PassWord = userObj.PassWord
		user.Phone = userObj.Phone
		user.RealName = userObj.RealName
		user.Status = userObj.Status
		//更新方式
		if mouthed == 2 {
			var old []string
			//需要删除的权限
			for _, i3 := range userObj.SystemUserRestriction {
				old = append(old, i3.ProjectId)
			}
			fmt.Println(userObj.SystemUserRestriction)
			var newRestriction []modelbase.SystemUserRestriction
			for _, restriction := range user.SystemUserRestriction {
				if arrays.ContainsString(old, restriction.ProjectId) == -1 {
					newRestriction = append(newRestriction, restriction)
				}
			}
			user.SystemUserRestriction = newRestriction
		} else {
			user.SystemUserRestriction = userObj.SystemUserRestriction
		}

		if err := tx.Save(&user).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

func (u *UserService) NewExcelBatchUpdate(userObj dao.SystemUser, mouthed int) (err error) {
	//1：新增权限；2：删除权限；3：覆盖权限）
	var _db = mysql.GetDB()
	err = _db.Transaction(func(tx *gorm.DB) error {
		var user dao.SystemUser
		query := map[string]interface{}{"user_id": userObj.UserId}
		if err := tx.Model(&dao.SystemUser{}).Preload(clause.Associations).Where(query).First(&user).Error; err != nil {
			return err
		}
		//保存新的数据
		user.TeamNumber = userObj.TeamNumber
		user.PassWord = userObj.PassWord
		user.Phone = userObj.Phone
		user.RealName = userObj.RealName
		user.Status = userObj.Status
		user.UserNumber = userObj.UserNumber
		user.NickName = userObj.NickName
		user.IsAuthentication = userObj.IsAuthentication
		user.IdCardNumber = userObj.IdCardNumber
		user.Email = userObj.Email
		user.AlipayAccount = userObj.AlipayAccount
		user.DeliveryAddress = userObj.DeliveryAddress
		user.Introduction = userObj.Introduction
		user.Balance = userObj.Balance

		if mouthed != 1 {
			//删除用户关联的 restriction中的数据
			if err := tx.Model(&dao.SystemUserRestriction{}).Where(map[string]interface{}{"system_user_id": user.Id}).Unscoped().Delete(&dao.SystemUserRestriction{}).Error; err != nil {
				return err
			}
		}
		//更新方式
		if mouthed == 2 {
			var old []string
			//需要删除的权限
			for _, i3 := range userObj.SystemUserRestriction {
				old = append(old, i3.ProjectId)
			}
			fmt.Println(userObj.SystemUserRestriction)
			var newRestriction []modelbase.SystemUserRestriction
			for _, restriction := range user.SystemUserRestriction {
				if arrays.ContainsString(old, restriction.ProjectId) == -1 { //不存在
					newRestriction = append(newRestriction, restriction)
				}
			}
			user.SystemUserRestriction = newRestriction
		} else {
			user.SystemUserRestriction = userObj.SystemUserRestriction
		}

		if err := tx.Save(&user).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

func (u *UserService) GetUserList(page, pageSize int64, wherestr []string) (res *dao.PageResponse[dao.SystemUser], err error) {
	var common CommonService[dao.SystemUser]
	common.Page = page
	common.PageSize = pageSize
	for _, s := range wherestr {
		common.WhereStr = append(common.WhereStr, s)
	}
	return common.SelectList()
}

func (u *UserService) VerifyAndQueryUserByUserId(userId string) (bool, *dao.SystemUser, error) {
	var serve CommonService[dao.SystemUser]
	serve.Query = map[string]interface{}{"user_id": userId}
	if count, err := serve.Count(); err != nil {
		return false, nil, err
	} else {
		if count == 0 {
			return false, nil, nil
		} else {
			if user, err := serve.First(); err != nil {
				return false, nil, err
			} else {
				return true, &user, nil
			}
		}
	}
}

func (u *UserService) VerifyAndQueryUser(id uint) (bool, *dao.SystemUser, error) {
	var serve CommonService[dao.SystemUser]
	serve.Query = map[string]interface{}{"id": id}
	if count, err := serve.Count(); err != nil {
		return false, nil, err
	} else {
		if count == 0 {
			return false, nil, nil
		} else {
			if user, err := serve.First(); err != nil {
				return false, nil, err
			} else {
				return true, &user, nil
			}
		}
	}
}

func (u *UserService) UpdateBalanceSubtract(id uint, balance float64) error {
	exist, user, err := u.VerifyAndQueryUser(id)
	if err != nil {
		return err
	}
	if !exist {
		return errors.New("该用户不存在")
	}
	if user.Balance < balance {
		return errors.New("该账户芝草余额不足")
	}

	var systemUserDao dao.Common[dao.SystemUser]
	systemUserDao.Query = map[string]interface{}{"id": id}
	return systemUserDao.Update(map[string]interface{}{"balance": gorm.Expr("balance - ?", balance)}).Error
}

func (u *UserService) UpdateBalanceAdd(id uint, balance float64) error {
	exist, _, err := u.VerifyAndQueryUser(id)
	if err != nil {
		return err
	}
	if !exist {
		return errors.New("该用户不存在")
	}
	var systemUserDao dao.Common[dao.SystemUser]
	systemUserDao.Query = map[string]interface{}{"id": id}
	return systemUserDao.Update(map[string]interface{}{"balance": gorm.Expr("balance + ?", balance)}).Error
}

func (u *UserService) UpdateEffectiveManpower(id uint) error {
	//更新用户数据
	var systemUserDao dao.Common[dao.SystemUser]
	systemUserDao.Query = map[string]interface{}{"id": id}
	systemUserDao.Update(map[string]interface{}{"is_effective_manpower": 1, "team_activation_date": time.Now()})
	return nil
}

func (u *UserService) UpdateTeam(id uint) error {
	//更新用户数据
	var systemUserDao dao.Common[dao.SystemUser]
	systemUserDao.Query = map[string]interface{}{"id": id}
	systemUserDao.Update(map[string]interface{}{"team_number": "zxz"})
	return nil
}

type UserBalanceStatisticsResponse struct {
	UserId                  string  `json:"user_id"`                     //用户ID
	Balance                 float64 `json:"balance"`                     //我的芝草
	BalanceDesc             string  `json:"balance_desc"`                //我的芝草说明
	MonthCashOutBalance     float64 `json:"month_cash_out_balance"`      //本月已兑换现金的芝草数量
	MonthCashOutBalanceDesc string  `json:"month_cash_out_balance_desc"` //本月已兑换现金说明
	HistoryInAmount         float64 `json:"history_in_amount"`           //历史累计获得芝草
	HistoryOutAmount        float64 `json:"history_out_amount"`          //历史累计支出芝草
}

func (u *UserService) UserBalanceStatistics(id uint) (*UserBalanceStatisticsResponse, error) {
	exist, user, err := u.VerifyAndQueryUser(id)
	if err != nil {
		return nil, err
	}
	if !exist {
		return nil, errors.New("该用户不存在")
	}
	var res UserBalanceStatisticsResponse
	res.UserId = user.UserId
	res.Balance = user.Balance
	var prdService SystemProductService
	var balanceLogService UserBalanceLogService
	if res.HistoryOutAmount, err = balanceLogService.GetHistoryOutBalance(user.UserId); err != nil {
		return nil, err
	}
	if res.HistoryInAmount, err = balanceLogService.GetHistoryBalance(user.UserId); err != nil {
		return nil, err
	}
	if res.MonthCashOutBalance, err = balanceLogService.GetMonthCashOutBalance(user.UserId); err != nil {
		return nil, err
	}
	prod, err := prdService.ProductFindCashProduct()
	if err != nil {
		//return nil, err
	} else {
		res.BalanceDesc = fmt.Sprintf("(%v芝草=1元)", prod.ProductPrice)
		//不考虑小数
		monthOutMoney := math.Round(res.MonthCashOutBalance / prod.ProductPrice)
		res.MonthCashOutBalanceDesc = fmt.Sprintf("(%v元)", monthOutMoney)
	}
	return &res, nil
}

func (u *UserService) VerifyUser(user string) (bool, *dao.SystemUser, error) {
	var serve CommonService[dao.SystemUser]
	serve.Query = map[string]interface{}{}
	serve.WhereStr = []string{}
	serve.WhereStr = append(serve.WhereStr, fmt.Sprintf("user_id = '%s' or phone = '%s' or email = '%s'", user, user, user))
	if count, err := serve.Count(); err != nil {
		return false, nil, err
	} else {
		if count == 0 {
			return false, nil, nil
		} else {
			if user, err := serve.First(); err != nil {
				return false, nil, err
			} else {
				return true, &user, nil
			}
		}
	}
}

func (u *UserService) BatchDelUser(ids []uint) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var common dao.Common[dao.SystemUser]
		common.Tx = tx

		if len(ids) > 0 {
			//删除用户权限
			if err := tx.Model(&dao.SystemUserRestriction{}).Unscoped().Where("system_user_id IN (?)", ids).Delete(&dao.SystemUserRestriction{}).Error; err != nil {
				return err
			}
			//删除用户
			if err := tx.Model(&dao.SystemUser{}).Unscoped().Where("id IN (?)", ids).Delete(&dao.SystemUser{}).Error; err != nil {
				return err
			}
		} else {
			//没传ID删所有可以删除的
			common.Query = map[string]interface{}{}
			canDelIds := tx.Model(&dao.SystemUser{}).Select("id")
			//删除用户权限
			if err := tx.Model(&dao.SystemUserRestriction{}).Unscoped().Where("system_user_id IN (?)", canDelIds).Delete(&dao.SystemUserRestriction{}).Error; err != nil {
				return err
			}
			//删除用户
			if err := tx.Model(&dao.SystemUser{}).Unscoped().Where("id IN (?)", canDelIds).Delete(&dao.SystemUser{}).Error; err != nil {
				return err
			}
		}

		return nil
	})
}

func (s *UserService) BatchImportDelUser(users []*dao.SystemUser) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var userDao dao.Common[dao.SystemUser]
		userDao.Tx = tx
		for _, user := range users {
			if err := tx.Model(&dao.SystemUser{}).Where(map[string]interface{}{"user_id": user.UserId}).Delete(&dao.SystemUser{}).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

func (u *UserService) GetUserWhiteList(page, pageSize int64, wherestr []string) (res *dao.PageResponse[dao.SystemUser], err error) {
	var common CommonService[dao.SystemUser]
	common.Page = page
	common.PageSize = pageSize
	common.LeftJoin = append(common.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_user_whitelist on tas_system_user.user_id = tas_system_user_whitelist.user_id "))
	common.WhereStr = append(common.WhereStr, fmt.Sprintf("tas_system_user_whitelist.user_id is not null"))
	field := "tas_system_user.*,tas_system_user_whitelist.user_id w_user_id"
	common.SelectField = &field
	for _, s := range wherestr {
		common.WhereStr = append(common.WhereStr, s)
	}
	return common.SelectList()
}

func (s *UserService) UserWhiteListImport(lists []*dao.SystemUserWhitelist) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var whiteListDao dao.Common[dao.SystemUserWhitelist]
		whiteListDao.Tx = tx
		if err := tx.Create(lists).Error; err != nil {
			return err
		}
		return nil
	})
}

func (s *UserService) UserWhiteListImportDel(lists []*dao.SystemUserWhitelist) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var whiteListDao dao.Common[dao.SystemUserWhitelist]
		whiteListDao.Tx = tx
		for _, user := range lists {
			if err := tx.Unscoped().Where("user_id = ?", user.UserId).Delete(user).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

func (s *UserService) UserWhiteListDel(userIds []string) error {
	var commonServe dao.Common[dao.SystemUserWhitelist]
	if len(userIds) > 0 {
		if err := commonServe.BatchDeleteByStringColumn("user_id", userIds).Error; err != nil {
			return err
		}
		return nil
	} else {
		if list, err := commonServe.FindAll(map[string]interface{}{}); err != nil {
			return err
		} else {
			var canDelIds []uint
			for _, model := range list {
				canDelIds = append(canDelIds, model.Id)
			}
			if err := commonServe.RemoveUnscopedWhere(map[string]interface{}{"id": canDelIds}).Error; err != nil {
				return err
			} else {
				return nil
			}
		}
	}
}
